package core.cwm;

import java.util.List;

import core.access.Read;
import core.access.Right;
import core.obj.Object;
import core.sub.Company;
import core.sub.Subject;

public class SSCondValidator implements Validator {

	@Override
	/**
	 * Assume that obj is companyData
	 */
	public boolean validate(Subject sub, Object obj, Right right) {
		boolean b = false;
		if(right instanceof Read) {
			b = validateSSCond1(sub, obj);
			if(!b)
				b = validateSSCond2(sub, obj);
			if(!b)
				b = validateSSCond3(sub, obj);
		}
		return b;
	}
	
	private boolean validateSSCond1(Subject sub, Object obj) {
		CompanyRecord CDs = CompanyRecord.getInstance();
		Company C = CDs.lookup(obj);
		if(C != null) {
			PRRecord PRs = PRRecord.getInstance();
			PRObject subPR = PRs.getPRObjects(sub);
			List<Object> subObjs = subPR.getObjects();
			if(subObjs != null) {
				for(int i=0;i<subObjs.size();i++) {
					Object o = subObjs.get(i);
					
					// Condition 1
					Company C_o = CDs.lookup(o);
					if(C_o != null) {
						if(C.equals(C_o)) {
							// Satisfy condition 1
							return true;
						}

					} else {
						// not company data, does not matter, just skip
					}
				}				
			} else {
				// subject has not read any object
				return true;
			}
		} else {
			// obj is an object not belong to any companies 
			// Pass to other validator or raise some errors			
		}
		return false;
	}

	private boolean validateSSCond2(Subject sub, Object obj) {
		CompanyRecord CDs = CompanyRecord.getInstance();
		Company C = CDs.lookup(obj);
		if(C != null) {
			PRRecord PRs = PRRecord.getInstance();
			COISet COIs = COISet.getInstance();
			PRObject subPR = PRs.getPRObjects(sub);
			List<Object> subObjs = subPR.getObjects();
			List<COI> obj_COIs = COIs.getCOIs(C);
			if(subObjs != null) {
				for(int i=0;i<subObjs.size();i++) {
					Object o = subObjs.get(i);
					
					Company C_o = CDs.lookup(o);
					if(C_o != null) {
						List<COI> o_COIs = COIs.getCOIs(C_o);
						// Condition 2
						for(int j=0;j<o_COIs.size();j++) {
							if(obj_COIs.contains(o_COIs.get(j))) {
								return false;
							}
						}
					} else {
						// not company data, does not matter, just skip
					}
				}
				// Satisfy condition 2
				return true;
			} else {
				// subject has not read any object
				return true;
			}
		} else {
			// obj is an object not belong to any companies 
			// Pass to other validator or raise some errors			
		}
		return false;
	}
	
	private boolean validateSSCond3(Subject sub, Object obj) {
		return obj.isSanitized();
	}	
}
